home *** CD-ROM | disk | FTP | other *** search
- ;****************************************************************************
- ; P S P . A S M
- ;============================================================================
- ; Functions to process data in the Program Segment Prefix (PSP).
- ;---------------------------------------------------------------------------
- ; Copyright (c) Simon Groes, 1994
- ;---------------------------------------------------------------------------
- ; Assemble with Borland Turbo Assembler v3.0
- ;****************************************************************************
-
- IDEAL
- DOSSEG
- MODEL small
-
- LOCALS
-
- ;----- Insert INCLUDE "filename" directives here
- INCLUDE "macro.inc"
- INCLUDE "common.inc"
-
- ;----- Insert EQU and = equates here
- TAIL_LENGTH = 0080h ; Offset of PSP length byte.
- COMMAND_TAIL = 0081h ; Offset of command tail.
- BUFLEN = 189 ; (see below).
-
-
- DATASEG
-
- ;----- Declare all PUBLIC variables here:
-
- ;----- Declare other variables with DB, DW, etc., here
-
- cmdBuf db BUFLEN DUP (0) ; Buffer to hold edited command tail.
- ;---------------------------------------------------------
- ; Note that the command tail in the PSP has a maximum of 127 chars,
- ; including <CR>, while this buffer can accommodate 189 chars.
- ; This is to allow for the unlikely situation when the command tail
- ; consists of 63 1-char switches (e.g. /x), a terminating <CR> & no
- ; spaces in between. However, each switch will be copied with a
- ; terminating NULL char (total 62) to this buffer.
- ; i.e. 126 + 62 + 1 = 189
- ;---------------------------------------------------------
- cBufLen db BUFLEN ; Used in GetNextParam.
-
- nParams db 0 ; # of parameters (incl switches).
- nSwitches db 0 ; # of switches.
-
-
- ;----- Specify any EXTRN variables here
-
- CODESEG
-
- ;----- Declare PUBLIC procedures here
- PUBLIC PSP_Parameters, GetParamNumber, GetSwNumber, GetNextParam
-
- ;===============================================================
- ; Procedure: =*=PSP_Parameters=*=
- ;---------------------------------------------------------------
- ; Access: Public - Available to other files.
- ; Task: To copy the parameters in the command tail of the
- ; PSP to a single buffer (supplied by the calling procedure)
- ; as a series of NULL-terminated strings.
- ; Input: none
- ; Output: Parameters copied to buffer as a series of
- ; NULL-terminated strings.
- ; di -> the buffer.
- ; si -> the buffer.
- ; Registers: ds -> Program's data segment.
- ; di -> cmdBuf.
- ; si -> cmdBuf.
- ; All other registers unchanged.
- ; Note: DS & ES registers always address the Program Segment
- ; Prefix (PSP) when all .EXE programs begin.
- ;===============================================================
- PROC PSP_Parameters
-
- SaveRegs <ax,bx,cx> ; Save modified register(s).
-
- mov ax, @data ; ES = Data Segment.
- mov es, ax
- ASSUME es:@data
- mov di, OFFSET cmdBuf ; DI -> cmdBuf
- mov bx, di ; BX -> cmdBuf for calculations.
- push di ; Save di.
-
- mov cl, [ds:TAIL_LENGTH] ; cl = Length of PSP command tail.
- xor ch, ch ; Clear rest of cx.
- mov si, COMMAND_TAIL ; si -> command tail.
- xor al, al ; al = NULL
-
- ;----- JUMP LEADING SPACES & TABS:
- cmp [BYTE ds:si], SPACE
- je @@1stParam
- cmp [BYTE ds:si], TAB
- je @@1stParam
- @@1stParam:
- call JumpSPABS
-
- ;----- MAIN LOOP BEGINS HERE..
- @@LOOP_BEGIN:
- cmp [BYTE ds:si], CR ; Is the char a carriage return ?
- je @@NoError ; Yes: No parameters. End.
- cmp [BYTE ds:si], NULL ; No : Is the char a NULL ?
- je @@Error ; Yes: End with error.
- cmp [BYTE ds:si], SPACE ; No : Is the char a space ?
- je @@NextParam ; Yes: Jump to next parameter.
- cmp [BYTE ds:si], TAB ; No : Is the char a tab ?
- je @@NextParam ; Yes: Jump to next parameter.
- cmp [BYTE ds:si], SW1 ; No : Is the char a '/' switch ?
- je @@Switch ; Yes: Follow routine for switches.
- cmp [BYTE ds:si], SW2 ; No : Is the char a '-' switch ?
- jne @@CopyChar ; No : Char is a param char.
- @@Switch:
- inc [es:nSwitches] ; Yes: Inc # of switches.
- cmp di, bx ; Is di at start of buffer ?
- je @@CopyChar ; Yes: Copy to buffer.
- or [BYTE es:di-1], 0 ; No : Is prev char 0 ?
- jz @@CopyChar ; Yes: Copy to buffer.
- stosb ; No : Add 0 to prev param.
- inc [es:nParams] ; Inc # of parameters.
- @@CopyChar:
- movsb ; [ds:si] -> [es:di]; inc si, inc di.
- jmp NEAR @@LOOP_END
- @@NextParam:
- call JumpSPABS ; si -> next param.
- inc cx ; 1st space/tab should not dec cx.
- stosb ; [es:di]=NULL, inc di.
- inc [es:nParams]
- @@LOOP_END:
- loop @@LOOP_BEGIN ; dec cx, if cx=0 break.
- ;----- MAIN LOOP ENDS HERE.
-
- @@TailEnd:
- ;----- SI -> last char (should be <CR>). DI -> end of param string list.
- or [BYTE es:di-1], 0 ; Is last param char 0 ?
- je @@20 ; Yes: Skip next instructions.
- inc [es:nParams] ; No : Inc # of parameters.
- @@20: cmp [BYTE ds:si], CR ; Is the last char a carriage return?
- jne @@Error ; No : End with error.
- stosb ; Change <CR> to NULL.
- @@NoError:
- clc ; No error.
- @@Return:
- smove ds, es ; ds -> Data Segment
- pop di ; di -> cmdBuf
- mov si, di ; si -> cmdBuf
- RestoreRegs <cx,bx,ax> ; Restore registers.
- ret ; Return to caller.
-
- @@Error:
- stc ; Set carry flag.
- jmp NEAR @@Return ; End routine.
- ENDP PSP_Parameters
-
- ;===============================================================
- ; Procedure: =*=JumpSPABS=*=
- ;---------------------------------------------------------------
- ; Access: Private - Not available to other files.
- ; Task: Jumps string of 1 or more spaces & tabs (SPABS).
- ; Input: si = Offset address of string of SPABS.
- ; cx = # of chars from si reg to end of command tail
- ; (not including CR at end).
- ; Output: si -> 1st char after SPABS (SPaces & tABS).
- ; Registers:
- ; si, di, cx changed.
- ;===============================================================
- PROC JumpSPABS
-
- push ax ; Save modified register(s).
- @@Repeat:
- mov al, [si] ; Get character at ds:si.
- cmp al, SPACE ; Is it a space?
- je @@Next ; Yes: Move to next char.
- cmp al, TAB ; No : Is it a tab?
- je @@Next ; Yes: Move to next char.
- jmp NEAR @@Return; No : si -> 1st char after SPABS; end.
- @@Next: inc si ; Move to next char.
- loop @@Repeat ; dec cx; if cx > 0, jmp @@Repeat.
- @@Return:
- pop ax
- ret ; Return to caller.
- ENDP JumpSPABS
-
- ;===============================================================
- ; Procedure: =*=GetParamNumber=*=
- ;---------------------------------------------------------------
- ; Access: Public - Available to other files.
- ; Task: Return # of parameters (including switches) in command tail.
- ; Input: none
- ; Output: ax = # of parameters in command tail.
- ; Registers: ax changed.
- ;===============================================================
- PROC GetParamNumber
-
- xor ah, ah ; Clear upper half of ax.
- mov al, [nParams] ; # of params in al.
- ret ; Return to caller.
- ENDP GetParamNumber
-
- ;===============================================================
- ; Procedure: =*=GetSwNumber=*=
- ;---------------------------------------------------------------
- ; Access: Public - Available to other files.
- ; Task: Return # of switches (e.g. /x) in command tail.
- ; Input: none
- ; Output: ax = # of switches in command tail.
- ; Registers: ax changed.
- ;===============================================================
- PROC GetSwNumber
-
- xor ah, ah ; Clear upper half of ax.
- mov al, [nSwitches] ; # of switches in al.
- ret ; Return to caller.
- ENDP GetSwNumber
-
- ;===============================================================
- ; Procedure: =*=GetNextParam=*=
- ;---------------------------------------------------------------
- ; Access: Public - Available to other .ASM files.
- ; Task: Point di to next param in command buffer.
- ; Input: di -> cmdBuf
- ; cmdBuf -> Parameters (PSP_Parameters should have
- ; already processed PSP.
- ; Output: di -> next parameter in cmdBuf.
- ; Registers: di changed.
- ;===============================================================
- PROC GetNextParam
-
- SaveRegs<ax,cx>
- mov al, NULL ; Char to find in al.
- mov cl, [cBufLen] ; Remaining buf length in cx.
- xor ch, ch
- jcxz @@Err ; If di -> end of buf, end with error.
- cld ; Auto increment.
- repnz scasb ; Search for NULL. di -> Next parameter.
- jcxz @@Err ; If di -> end of buf, end with error.
- clc ; Else, no error.
- @@Rtn: mov [cBufLen], cl ; Save remaining buf length in variable.
- RestoreRegs<cx,ax>
- ret ; Return to caller.
- @@Err: stc ; Error.
- jmp @@Rtn ; End program.
- ENDP GetNextParam
-
- END ; End of module.
-